package ua.amsoft.brelok.chart;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.achartengine.chart.BarChart;
import org.achartengine.model.CategorySeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.SimpleSeriesRenderer;
import org.achartengine.renderer.XYMultipleSeriesRenderer;

import ua.amsoft.brelok.dto.ChartRendererParameters;
import android.graphics.Paint.Align;

/**
 * @author Tair Mustafaiev
 */
public class BrelokBarChartDrawer {
    
    private final XYMultipleSeriesRenderer renderer;
    
    private final ChartRendererParameters rendererParameters;
    
    /**
     * Constructor
     * 
     * @param renderer - cannot be null
     * @param rendererParameters - cannot be null
     */
    public BrelokBarChartDrawer(final XYMultipleSeriesRenderer renderer,
            final ChartRendererParameters rendererParameters) {
        this.renderer = renderer;
        this.rendererParameters = rendererParameters;
    }
    
    /**
     * Executes the chart demo.
     * 
     * @return the built intent
     */
    public BarChart execute() {
        final XYMultipleSeriesDataset dataset = buildBarDataset();
        this.renderer.setXLabelsAlign(Align.CENTER);
        this.renderer.setYLabelsAlign(Align.RIGHT);
        this.renderer.setPanEnabled(true, false);
        this.renderer.setAxisTitleTextSize(16);
        this.renderer.setChartTitleTextSize(20);
        this.renderer.setLabelsTextSize(15);
        this.renderer.setLegendTextSize(15);
        buildColors();
        final BarChart chart = new BarChart(dataset, this.renderer,
                this.rendererParameters.getType());
        return chart;
    }
    
    /**
     * Builds a bar multiple series renderer to use the provided colors.
     */
    private void buildColors() {
        final int[] colors = this.rendererParameters.getColors();
        if (colors != null) {
            final int length = colors.length;
            for (int i = 0; i < length; i++) {
                final SimpleSeriesRenderer ssr = new SimpleSeriesRenderer();
                ssr.setColor(colors[i]);
                this.renderer.clearXTextLabels();
                this.renderer.addXTextLabel(1, "Вересень");
                this.renderer.addXTextLabel(2, "Жовтень");
                this.renderer.addXTextLabel(3, "Листопад");
                this.renderer.addXTextLabel(4, "Грудень");
                this.renderer.addSeriesRenderer(ssr);
            }
        }
    }
    
    /**
     * Builds a bar multiple series dataset using the provided values.
     * 
     * @return the XY multiple bar dataset
     */
    private XYMultipleSeriesDataset buildBarDataset() {
        final XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
        final Map<String[], List<double[]>> chartValues = this.rendererParameters.getChartValues();
        if (chartValues != null) {
            buildDataset(dataset, chartValues);
        }
        return dataset;
    }
    
    /**
     * Builds dataset for chart
     * 
     * @param dataset
     * @param chartValues
     */
    private void buildDataset(final XYMultipleSeriesDataset dataset,
            final Map<String[], List<double[]>> chartValues) {
        final Set<Entry<String[], List<double[]>>> entries = chartValues.entrySet();
        if ((entries != null) && !entries.isEmpty()) {
            final Iterator<Entry<String[], List<double[]>>> it = entries.iterator();
            while (it.hasNext()) {
                final Map.Entry<String[], List<double[]>> entry = it.next();
                buildChartElements(dataset, entry);
            }
        }
    }
    
    /**
     * Builds chart elements
     * 
     * @param dataset
     * @param entry
     * @param length
     */
    private void buildChartElements(final XYMultipleSeriesDataset dataset,
            final Map.Entry<String[], List<double[]>> entry) {
        if (entry != null) {
            final int length = entry.getKey().length;
            for (int j = 0; j < length; j++) {
                final CategorySeries series = new CategorySeries(entry.getKey()[j]);
                final double[] v = entry.getValue().get(j);
                for (final double value : v) {
                    series.add(value);
                }
                dataset.addSeries(series.toXYSeries());
            }
        }
    }
}
